'''
版权：Copyright (c) 2019 China

创建日期：Sunday November 10th 2019
创建者：ymq(ymq) - <<email>>

修改日期: Sunday, 10th November 2019 6:17:41 pm
修改者: ymq(ymq) - <<email>>

说明
 1、长者补贴账户每月结算和储值管理
'''
import uuid
import pandas as pd
from datetime import datetime
from server.pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...service.mongo_bill_service import MongoBillFilter
from ...service.buss_pub.bill_manage import BillManageService, OperationType, Status, TypeId
from ...service.constant import AccountType, AccountStatus, PayType, PayStatue, plat_id, SubsidyRecordState, UserType, UserCategory, SubsidyRecordSubsidyType


class SubsidyElderManage(MongoService):

    process_collection = 'PT_Financial_Receivable_Process'
    account_collection = 'PT_Financial_Account'
    record_collection = 'PT_Financial_Account_Record'
    divide_collection = 'PT_Financial_Divide_Record'
    user_collection = 'PT_User'
    subsidy_collection = 'PT_Subsidy_Record'

    def __init__(self, db_addr, db_port, db_name, inital_password, session):
        self.db_addr = db_addr
        self.db_port = db_port
        self.db_name = db_name
        self.inital_password = inital_password
        self.session = self.session
        self.bill_manage_server = BillManageService(
            self.db_addr, self.db_port, self.db_name, self.inital_password, self.session)

    def total_task(self):
        self.clean_task()
        self.recharg_task()

    def clean_task(self):
        # 待结算长者id
        account_ids = self.__get_clean_account_list()
        # 冻结待结算的长者补贴账户
        self.frozen_elder_subsidy_account(account_ids, AccountStatus.frozen)
        # 清空待结算长者补贴账户余额
        self.clean_elder_subsidy_account(account_ids)
        # 解冻待计算的长者补贴账户
        self.frozen_elder_subsidy_account(account_ids, AccountStatus.normal)

    def recharg_task(self):
        # 待拨款长者id
        account_ids = self.__get_recharg_account_list()
        # 冻结待拨款的长者补贴账户
        self.frozen_elder_subsidy_account(account_ids, AccountStatus.frozen)
        # 给长者的补贴账户拨款
        self.recharg_elder_subsidy_account(account_ids)
        # 解冻长者补贴账户
        self.frozen_elder_subsidy_account(account_ids, AccountStatus.normal)

    def __get_clean_account_list(self):
        '''获取待结算的长者的补贴账户列表
            补贴账户余额大于0的长者账户全部清零余额
        '''
        _filter = MongoBillFilter()
        _filter.match_bill((C('account_type') == AccountType.account_subsidy)
                           & (C('balance') > 0)
                           & (C('account_status') == AccountStatus.normal))\
               .inner_join_bill(self.user_collection, 'user_id', 'id', 'user_info')\
               .match((C('user_info.personnel_type') == UserType.Personnel)
                      & (C('user_info.personnel_info.personnel_category') == UserCategory.Elder))\
               .project({'_id': 0, 'id': 1})
        res = self.query(_filter, self.account_collection)
        return res

    def __get_recharg_account_list(self):
        '''获取待充值的补贴账户列表
           返回补贴账户id和补贴金额
        '''
        time_now = datetime.now()
        _filter = MongoBillFilter()
        _filter.match_bill((C('subsidy_type') == SubsidyRecordSubsidyType.Seniors)
                           & (C('state') == SubsidyRecordState.valid)
                           & (C('begin_date') > time_now)
                           & (C('end_date') < time_now))\
               .inner_join_bill(self.account_collection, 'user_id', 'user_id', 'account_info')\
               .match(C('account_info.account_type') == AccountType.account_subsidy)\
               .project({'_id': 0, 'account_id': '$account_info.id', 'amount': 1})
        res = self.query(_filter, self.subsidy_collection)
        return res

    def frozen_elder_subsidy_account(self, account_ids, account_status):
        '''冻结/解冻账户
        Args:
        account_ids:待操作的账户id列表
        account_status:变更的目标账户状态
        '''
        update_data_list = []
        for i in account_ids:
            update_data_list.append(dict({'account_status': account_status}, **i))
        if len(update_data_list) > 0:
            self.bill_manage_server.add_bill(
                OperationType.update.value, TypeId.financial.value, update_data_list, self.account_collection)

    def clean_elder_subsidy_account(self, account_ids):
        '''清空账户余额'''
        clean_account_list = []
        clean_record_list = []
        for i in account_ids:
            balance = self.__get_account_balance(i['id'])
            clean_account_list.append(dict({'balance': 0}, **i))
            clean_record_list.append({'account_id': i['id'], 'amount': balance *
                                      (-1), 'balance': 0, 'abstract': '补贴账户结算', 'date': datetime.now()})
        self.bill_manage_server.add_bill(
            OperationType.update.value, TypeId.financial.value, clean_account_list, self.account_collection)
        self.bill_manage_server.add_bill(
            OperationType.add.value, TypeId.financial.value, clean_record_list, self.record_collection)

    def recharg_elder_subsidy_account(self, account_ids):
        '''充值补贴账户'''
        recharge_account_list = []
        recharge_record_list = []
        for i in account_ids:
            recharge_account_list.append({'id': i['account_id'], 'balance': i['amount']})
            recharge_record_list.append(
                dict({'balance': i['amount'], 'abstract': '补贴金额发放', 'date': datetime.now()}, **i))
        self.bill_manage_server.add_bill(
            OperationType.update.value, TypeId.financial.value, recharge_account_list, self.account_collection)
        self.bill_manage_server.add_bill(
            OperationType.add.value, TypeId.financial.value, recharge_record_list, self.record_collection)

    def __get_account_balance(self, account_id):
        '''冻结账户后获取账户余额'''
        _filter = MongoBillFilter()
        _filter.match_bill(C('account_id') == account_id)\
               .sort({'date': -1})\
               .limit(1)
        res = self.query(_filter, self.record_collection)
        if len(res) == 0:
            return 0
        else:
            return res[0]['balance']
